ssh 进阶使用技巧

前言

曾经我天真得以为所有的服务器都可以直接用 ssh username@hostname 直接登陆,后来发现我还是太天真了。

很多开发工具也像我一样天真,相关的配置项很少。只要使用一次跳板机的时候我凑合使用 -J 参数连上了,这次碰到需要使用两次跳板机的情况,我此前所有工具的远程管理都挂了,无法正常使用。

因此我决定系统学习一遍 ssh,争取在各种网络条件下都能通过配置 ~/.ssh/config 的方式,使网络条件对开发工具透明化。

什么是 SSH

维基百科的定义:https://zh.wikipedia.org/zh-hans/Secure_Shell
Secure Shell(安全外壳协议,简称 SSH)是一种加密的网络传输协议,以非对称加密实现身份验证,可在不安全的网络中为网络服务提供安全的传输环境。

我们常用的 ssh 指令是 OpenSSH SSH client,是 SSH 的一个实现,是一个远程登陆程序。今天提到的主人公也就是这个程序,将要学习的是这个程序的应用。

1
2
ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-B bind_interface] [-b bind_address] [-c cipher_spec] [-D [bind_address:]port] [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11] [-i identity_file] [-J destination]
[-L address] [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] [-Q query_option] [-R address] [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]] destination [command]

术语解析

这里有两个相关但又有区别的术语需要区分:端口映射和隧道协议

  • 端口映射,英文为 port forwarding/port mapping,是 NAT 技术的应用,特征是在一个公网 IP 内部。
  • 隧道协议,是一种将另一种协议内容封装在负载部分的网络协议,特征是封装和加密。

不论如何分类,ssh 都工作在 TCP/IP 参考模型的应用层,基于 TCP 协议工作,并且经常同时使用这两项技术。

ssh(OpenSSH SSH client)的用途

阅读手册 http://linux.51yip.com/search/sshman ssh

通用的不常见的参数:
-f 后台运行
-a/A 禁止/开启客户端连接转发
-G 打印配置并退出
-g 允许远程主机连接到本地转发端口
-N 不要远程执行指令
-v 冗余模式用于调试

远程登录,执行命令

最基本用途。
-J destination 可以通过 destination 作为跳板机远程登陆其他主机。多次跳转使用逗号分隔。与 ProxyJump 配置相关。 若这里使用域名,则在对应一跳的服务器上进行解析。
-M 开启主模式,用于连接复用。与 ControlMaster 配置相关。

端口转发

-D 本地动态应用层端口转发
-L 本地静态端口转发
-R 远程静态端口转发

其他:隧道协议等奇怪的协议转发

-w 隧道相关
-K -k 与 GSSAPI credentials 相关
-X -x X11 相关
还可以集成到其他工具的传输层,例如 sftp

配置文件

参数配置有三个层次,命令行参数 > 某个用户的配置文件 > 系统所有用户的配置文件。通常修改某个用户的配置文件较好,所以后面也都是指某个用户的配置文件。

默认的相关文件目录为 ~/.ssh/
配置文件为 ~/.ssh/config
授权公钥为 ~/.ssh/authorized_keys
配置时注意一下文件的访问权限,网上到处都有。
别人的博客 https://www.hi-linux.com/posts/14346.html 很多讲的比较全面,这里只记我感兴趣的。
配置文件可以灵活配置所有主机的登陆参数,因此所有登陆参数放到这里可以将指令简化很多。

常用配置

StrictHostKeyChecking=no 自动接受新的公钥,这个会降低安全性
Host 配置项标识了一个配置区段,类似于配置路由。
HostName 远程主机名,可以直接使用数字 IP 地址。
IdentityFile 私钥文件路径。
Port 远程主机端口号
User 登陆用户名
UserKnownHostsFile 一个或多个用户认证主机缓存文件,全局为 GlobalKnownHostsFile

通配符

1
2
3
'*' 代表 0~n 个非空白字符。
'?' 代表一个非空白字符。
'!' 表示例外通配。

ControlMaster

据说有很多好处,只要把下面一段拷进配置文件即可。

1
2
3
4
5
6
Host *
ServerAliveInterval 10
TCPKeepAlive yes
ControlPersist yes
ControlMaster auto
ControlPath ~/.ssh/master_%r_%h_%p

https://www.ibm.com/developerworks/community/blogs/IBMzOS/entry/20150502?lang=en

ProxyJump

可以配置上一跳服务器,解决嵌套的跳板机登陆配置复杂的问题。
别人的文章 https://zhuanlan.zhihu.com/p/55016458

按照该方法配置 ProxyJump 后,ssh hostname 即可远程登陆。

各种 Forward 参数

DynamicForward、LocalForward、RemoteForward 这三个参数就对应着端口转发的三种方式。
别人的文章 https://starkandwayne.com/blog/setting-up-an-ssh-tunnel-with-ssh-config/
根据我的需求,将本地 2222 转发到执行远程服务器的 22 端口,弄好配置文件

1
2
3
4
5
6
7
Host my-proxy
Hostname x.x.x.x
User admin-user
IdentityFile ~/.ssh/id_rsa
LocalForward localhost:2222 remote_host:22
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h:%p

以及快捷指令

1
2
3
4
## For My Proxy Tunnel
alias proxy-on='ssh -fN my-proxy'
alias proxy-check='ssh -O check my-proxy'
alias proxy-off='ssh -O exit my-proxy'

之后用到需要连接 remote_host:22 上 ssh tunnel 的地方都可以使用 localhost:2222 这个端口来代替

坚持原创技术分享,您的支持将鼓励我继续创作!